#ifndef __NETDEC_H__
#define __NETDEC_H__

#include "input.hpp"
#include "packet.hpp"
#include "decoder.hpp"

/****************************************
 Adding new decoder
 1 of 2. Add new decoder header file
****************************************/
#include "mod-ether.hpp"
#include "mod-ipv4.hpp"
#include "mod-ipv6.hpp"
#include "mod-tcp.hpp"
#include "mod-udp.hpp"
#include "mod-icmp4.hpp"
#include "mod-icmp6.hpp"

#include <string>

using namespace std;

class Netdec
{
private:
  InputPort iport;
  Packet pkt;
  DecType head;
  Decoder * dec[DECODER_COUNT];

  enum {
    REAL_BEGIN = 0,
    REAL_NOW,
    REAL_CHECK,
    PKT_BEGIN,
    PKT_CHECK,
    PKT_NOW,
    TV_COUNT,
  };
  struct timeval tval[TV_COUNT];
  unsigned long long int tCount, tSize, dCount, dSize;
  double realBps, realPps, realSpan, pktBps, pktPps, pktSpan;
  string errmsg;

  inline void recordPerformance ();
  void setErrMsg (string e) { this->errmsg += e; }

public:
  NDecResult res;
  Timer timer;

  Netdec ();
  ~Netdec () ;

  /* for setup */
  bool setup (); /* general setup function */
  bool setupDevice (string devName, string filter = "");
  bool setupFile  (string fileName, string filter = "");

  /* for action */
  NDecResult * fetch ();

  /* for result */
  NDecFilter * makeFilter (string name, string arg = "");
  NDecMpxFilter * makeMpxFilter (string name);

  /* for performance */
  void beat ();
  double getDeltaSpan ();
  double getDeltaPPS ();
  double getDeltaBPS ();
  double getTotalSpan ();
  double getTotalPPS ();
  double getTotalBPS ();
  inline unsigned long long int getTotalPkt () { return this->tCount; }
  inline unsigned long long int getTotalSize () { return this->tSize; }

  string & getErrMsg () { return this->errmsg; }
};



#endif /* __NETDEC_H__ */
